package com.plian.system.service.fr.annualreport.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.plian.Tools.BigDecimalUtil;
import com.plian.Tools.DateUtil;
import com.plian.Tools.StringUtil;
import com.plian.system.bean.fr.AnnualReportExcelBean;
import com.plian.system.constant.sys.FormStatusConstant;
import com.plian.system.constant.yth.YthConstant;
import com.plian.system.entity.fr.annualreport.AnnualReport;
import com.plian.system.entity.sys.Org;
import com.plian.system.excel.ImportExcelUtil;
import com.plian.system.mapper.fr.annualreport.AnnualReportMapper;
import com.plian.system.service.fr.annualreport.IAnnualReportService;
import com.plian.system.service.sys.orgzation.IOrgService;
import com.plian.system.service.yth.helper.YthExcelUtils;
import com.plian.system.vo.yth.YthExcelInfoVO;
import com.plian.system.vo.yth.YthResult;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.plian.system.constant.sys.FormStatusConstant.FINISH;
import static com.plian.system.constant.sys.FormTypeConstant.FR_BULLETIN;
import static com.plian.system.constant.yth.YthConstant.EXCEL_MERGE;
import static com.plian.system.constant.yth.YthConstant.EXCEL_SINGLE;

@Slf4j
@Service
@AllArgsConstructor
public class AnnualReportServiceImpl extends ServiceImpl<AnnualReportMapper, AnnualReport> implements IAnnualReportService {

    private IOrgService orgService;

    private final List<String> NOT_UPDATE_STATUS = Stream
            .of(FormStatusConstant.FLOW + "", FormStatusConstant.FINISH + "").collect(Collectors.toList());

    @Override
    public String ythExcelUpload(YthExcelInfoVO ythExcelInfoVO, MultipartFile multipartFile) {
        if (multipartFile == null){
            return JSON.toJSONString(YthResult.builder().failReason("文件为空!"));
        }
        Org org = orgService.getByDataSourceId(YthConstant.DATA_NINGBO, ythExcelInfoVO.getOrgId());
        if (org == null){
            return JSON.toJSONString(YthResult.builder().failReason(StringUtil.format("orgId = {} ,该单位不存在!", ythExcelInfoVO.getOrgId())));
        }
        int summaryCode = orgService.getSummaryCode(org);
        if (ythExcelInfoVO.getValueType() == EXCEL_MERGE){
            summaryCode = summaryCode - 1;
        }
        if ("3".equals(org.getTypeCode())){
            if (ythExcelInfoVO.getValueType() == EXCEL_SINGLE || ythExcelInfoVO.getValueType() == EXCEL_SINGLE){
                summaryCode = summaryCode + 1;
            }
        }

        String tableTypeCode = YthExcelUtils.valueTypeToTableType(ythExcelInfoVO.getValueType());
        AnnualReport oldAnnualReport = getOne(Wrappers.<AnnualReport>lambdaQuery()
                .eq(AnnualReport::getOrgId, org.getId())
                .likeRight(AnnualReport::getReportTime, ythExcelInfoVO.getReportTime())
                .eq(AnnualReport::getSummaryCode, summaryCode)
                .eq(AnnualReport::getTableTypeCode, tableTypeCode));
        if (oldAnnualReport != null && NOT_UPDATE_STATUS.contains(oldAnnualReport.getStatus())){
            return JSON.toJSONString(YthResult.builder()
                    .failReason(StringUtil.format("orgId = {} ,valueType = {}, reportTime = {},该单据已上报!",
                            ythExcelInfoVO.getOrgId(), ythExcelInfoVO.getValueType(), ythExcelInfoVO.getReportTime())));
        }

        if (oldAnnualReport == null){
            oldAnnualReport = new AnnualReport();
            oldAnnualReport.setReportTime(DateUtil.parse(ythExcelInfoVO.getReportTime() + "-12-31", DateUtil.PATTERN_DATE));
            oldAnnualReport.setOrgId(org.getId());
            oldAnnualReport.setStatus(FINISH + "");
            oldAnnualReport.setFormType(String.valueOf(FR_BULLETIN));
            oldAnnualReport.setSummaryCode(summaryCode);
            oldAnnualReport.setTableTypeCode(tableTypeCode);
        }

        try {
            byte[] bytes = IOUtils.toByteArray(multipartFile.getInputStream());
            InputStream inputStream = new ByteArrayInputStream(bytes);
            List<Object> readList = new ArrayList<>();
            EasyExcel.read(inputStream).build()
                    .read(EasyExcel.readSheet(0).headRowNumber(1).head(AnnualReportExcelBean.class)
                            .registerReadListener(new PageReadListener<>(list -> readList.addAll(list))).build());
            ImportExcelUtil.filterEmpty(readList);
            for (Object object : readList){
                AnnualReportExcelBean excelBean = (AnnualReportExcelBean)object;
                String typeName = StringUtil.isNotBlank(excelBean.getTypeName()) ? StringUtil.cleanChars(excelBean.getTypeName()) : "";
                if (StringUtil.isBlank(typeName)){
                    continue;
                }
                switch (typeName){
                    case "资产总计":
                        oldAnnualReport.setZczj(BigDecimalUtil.toBigdecimal(excelBean.getYearAmount()));
                        oldAnnualReport.setLastZczj(BigDecimalUtil.toBigdecimal(excelBean.getLastYearAmount()));
                        break;
                    case "负债合计":
                        oldAnnualReport.setFzhj(BigDecimalUtil.toBigdecimal(excelBean.getYearAmount()));
                        oldAnnualReport.setLastFzhj(BigDecimalUtil.toBigdecimal(excelBean.getLastYearAmount()));
                        break;
                    case "净资产合计":
                        oldAnnualReport.setSyzqyhj(BigDecimalUtil.toBigdecimal(excelBean.getYearAmount()));
                        oldAnnualReport.setLastSyzqyhj(BigDecimalUtil.toBigdecimal(excelBean.getLastYearAmount()));
                        break;
                    case "营业总收入":
                        oldAnnualReport.setYyzsr(BigDecimalUtil.toBigdecimal(excelBean.getYearAmount()));
                        oldAnnualReport.setLastYyzsr(BigDecimalUtil.toBigdecimal(excelBean.getLastYearAmount()));
                        break;
                    case "利润总额":
                        oldAnnualReport.setLrze(BigDecimalUtil.toBigdecimal(excelBean.getYearAmount()));
                        oldAnnualReport.setLastLrze(BigDecimalUtil.toBigdecimal(excelBean.getLastYearAmount()));
                        break;
                    case "净利润":
                        oldAnnualReport.setJlr(BigDecimalUtil.toBigdecimal(excelBean.getYearAmount()));
                        oldAnnualReport.setLastJlr(BigDecimalUtil.toBigdecimal(excelBean.getLastYearAmount()));
                        break;
                    case "本年应交税费总额":
                        oldAnnualReport.setBnyjsfze(BigDecimalUtil.toBigdecimal(excelBean.getYearAmount()));
                        oldAnnualReport.setLastBnyjsfze(BigDecimalUtil.toBigdecimal(excelBean.getLastYearAmount()));
                        break;
                    case "带息负债年末余额":
                        oldAnnualReport.setDxfznmye(BigDecimalUtil.toBigdecimal(excelBean.getYearAmount()));
                        oldAnnualReport.setLastDxfznmye(BigDecimalUtil.toBigdecimal(excelBean.getLastYearAmount()));
                        break;
                    case "利息支出总额":
                        oldAnnualReport.setLxzcze(BigDecimalUtil.toBigdecimal(excelBean.getYearAmount()));
                        oldAnnualReport.setLastLxzcze(BigDecimalUtil.toBigdecimal(excelBean.getLastYearAmount()));
                        break;
                    case "其中：利息资本化金额":
                        oldAnnualReport.setLxzbhje(BigDecimalUtil.toBigdecimal(excelBean.getYearAmount()));
                        oldAnnualReport.setLastLxzbhje(BigDecimalUtil.toBigdecimal(excelBean.getLastYearAmount()));
                        break;
                    case "其中：利息费用":
                        oldAnnualReport.setLxfy(BigDecimalUtil.toBigdecimal(excelBean.getYearAmount()));
                        oldAnnualReport.setLastLxfy(BigDecimalUtil.toBigdecimal(excelBean.getLastYearAmount()));
                        break;
                    case "资产负债率（%）":
                        oldAnnualReport.setZcfzl(BigDecimalUtil.toBigdecimal(excelBean.getYearAmount()));
                        oldAnnualReport.setLastZcfzl(BigDecimalUtil.toBigdecimal(excelBean.getLastYearAmount()));
                        break;
                    case "流动比率":
                        oldAnnualReport.setLdbl(BigDecimalUtil.toBigdecimal(excelBean.getYearAmount()));
                        oldAnnualReport.setLastLdbl(BigDecimalUtil.toBigdecimal(excelBean.getLastYearAmount()));
                        break;
                    case "国有资本回报率（%）":
                        oldAnnualReport.setGyzbzbhbl(BigDecimalUtil.toBigdecimal(excelBean.getYearAmount()));
                        oldAnnualReport.setLastGyzbzbhbl(BigDecimalUtil.toBigdecimal(excelBean.getLastYearAmount()));
                        break;
                    case "国有资本保值增值率（%）":
                        oldAnnualReport.setGyzbbzzzl(BigDecimalUtil.toBigdecimal(excelBean.getYearAmount()));
                        oldAnnualReport.setLastGyzbbzzzl(BigDecimalUtil.toBigdecimal(excelBean.getLastYearAmount()));
                        break;
                }
            }
            saveOrUpdate(oldAnnualReport);
        }catch (Exception e){
            log.error(ExceptionUtils.getFullStackTrace(e));
            throw new RuntimeException(e);
        }
        return JSON.toJSONString(YthResult.builder().successIds(Stream.of(ythExcelInfoVO.getFormId()).collect(Collectors.toList())));
    }
}
